﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SuperKit {
    /*
     * 这个项目的功能是将文件按照数量合并到一个目录里面。
     * 比如说这个目录下有100个文件，如果分页数量是10，那么会分成10个目录，分别存放10个文件。
     */
    class SplitText : CommandExecutor {
        private const string DIR_NAME = "(_CLIPS)";

        // 每个文章的数量
        private int pageCount;
        // 每个分组的数量（多少个文件一个组）
        private int groupCount;

        private FileInfo[] files;
        // 当前文章的COUNT
        private int fileIndex;

        public SplitText(ArgReader arg, IExecutorOwner form, string fpath) : base(arg, form, fpath) {
            pageCount = arg.GetInteger("-pageCount", 50000);
            groupCount = arg.GetInteger("-groupCount", 8);
        }

        public override void Execute() {
            files = GetSortFiles(FilePath);
            fileIndex = 0;

            foreach (var file in files) {
                if (!Kit.IsFileType(file, ".txt")) {
                    continue;
                }

                Flush($"操作:{file.Name}");

                ProcessFile(file);
            }

            End();
        }

        private void ProcessFile(FileInfo file) {
            int currentIndex = 0;
            int groupIndex = 0;
            int groupLength = 0;
            string pureName = Path.GetFileNameWithoutExtension(file.Name);
            string filename = Path.Combine(FilePath, $"{pureName}_{currentIndex:D5}.txt");

            // 用来保存行的
            List<string> lines = new List<string>();
            int text_length = 0;

            using (StreamReader sr = new StreamReader(file.FullName)) {
                string line;
                while ((line = sr.ReadLine()) != null) {
                    line = line.Trim();
                    if (line.Length > 0) {
                        lines.Add(line);
                        text_length += line.Length;
                    }
                    // 如果蓄满了，写入
                    if (text_length > pageCount) {
                        WriteToFile(file, lines, groupIndex, currentIndex);
                        text_length = 0;
                        currentIndex++;
                        groupLength++;
                        lines.Clear();
                        if (groupLength >= groupCount) {
                            groupIndex++;
                            groupLength = 0;
                        }
                    }
                }
            }
        }

        private void WriteToFile(FileInfo file, List<string> lines, int groupIndex, int currentIndex) {
            string pureName = Path.GetFileNameWithoutExtension(file.Name);
            string filename = Path.Combine(FilePath, DIR_NAME, $"{pureName}_{groupIndex:D4}", $"{pureName}_{currentIndex:D5}.txt");
            EstablishDirectory(filename);
            using (StreamWriter writer = new StreamWriter(filename)) {
                foreach (string line in lines) {
                    writer.WriteLine(line);
                }
            }
        }

        private int GetPage(int index) {
            return index / pageCount + (index % pageCount > 0 ? 1 : 0);
        }

        public static FileInfo[] GetSortFiles(string path) {
            DirectoryInfo dir = new DirectoryInfo(path);
            var files = dir.GetFiles();
            List<FileInfo> list = new List<FileInfo>();
            foreach (var i in files) {
                list.Add(i);
            }
            list.Sort((a, b) => {
                return a.Name.CompareTo(b.Name);
            });
            for (int i = 0; i < files.Length; i++) {
                files[i] = list[i];
            }
            return files;
        }
    }
}
